﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;

namespace Billing.Win
{
    [ToolboxItem(true)]
    public partial class ucClientEdit : Billing.WindowsBase.CustomControls.BaseControl
    {
        #region Constants
        private const string msgNameMissing = "იურიდიული პირის სახელი არ არის მითითებული.";
        private const string msgClientMissing = "იურიდიული პირი არ არის არჩეული.";
        private const string msgClientStatusMissing = "აირჩიეთ კლიენტის სტატუსი";
        private const string msgClientTypeMissing = "აირჩიეთ კლიენტის ტიპი";
        private const string msgTaxMissing = "აირჩიეთ დღგ-ს დარიცხვის მეთოდი";

        private const string msgClientNameCleared = "თქვენ გაასუფთავეთ მომხმარებლის სახელი. ამის გამო სტატუსი ავტომატურად იცვლება პასიურზე";
        private const string msgClientAddressCleared = "თქვენ გაასუფთავეთ მომხმარებლის მისამართი. ამის გამო სტატუსი ავტომატურად იცვლება პასიურზე";
        private const string msgClientIdentificationNumberCleared = "თქვენ გაასუფთავეთ მომხმარებლის საიდენტიფიკაციო კოდი. ამის გამო სტატუსი ავტომატურად იცვლება პასიურზე";
        private const string msgTaxChangeQuestion = "დარწმუნებული ხართ, რომ გსურთ კლიენტის დღგ-ს სტატუსის ცვლილება?";
        private const string msgTaxChange = "თქვენ შეცვალეთ კლიენტის დღგ-ს სტატუსი, რაც იწვევს დარიცხვის მეთოდის შეცვლას. დაათვალიერეთ მაკორექტირებელი გატარებების სია.";
        #endregion

        #region Events
        public event EventHandler Canceled;
        public event EventHandler Saved;
        public event EventHandler CloseRequest;
        #endregion

        #region Constructors
        public ucClientEdit()
        {
            InitializeComponent();

            if (!this.DesignMode)
            {
                LoadDictionaryData();
                lbBalance.Visible = true;
            }
            this.btBalance.Visible = false;
        }

        public ucClientEdit(IBindingList itemList, Billing.DataObjects.ClientsView client)
            : this()
        {
            Initialize(itemList, client);
        }
        #endregion

        #region Properties & Fields
        Billing.DataObjects.BillingDataContext context = new Billing.DataObjects.BillingDataContext();

        private Billing.DataObjects.ClientsView client;
        private Billing.DataObjects.ClientsView tmpClient;

        IBindingList itemList;
        private Billing.WindowsBase.eOpenMode openMode;

        public Billing.DataObjects.ClientsView Client
        {
            get { return client; }
            set { client = value; }
        }

        public Billing.DataObjects.ClientsView TmpClient
        {
            get { return tmpClient; }
            set { tmpClient = value; }
        }

        public Billing.WindowsBase.eOpenMode OpenMode
        {
            get { return openMode; }
            set { openMode = value; }
        }

        public Infragistics.Win.Misc.UltraGroupBox ParameteresBox
        {
            get
            {
                return BaseControl_Fill_Panel;
            }
        }

        public Infragistics.Win.Misc.UltraGroupBox PhonesBox
        {
            get
            {
                return new Infragistics.Win.Misc.UltraGroupBox();
            }
        }
        #endregion

        public void Initialize(IBindingList itemList, Billing.DataObjects.ClientsView client)
        {
            if (itemList == null)
            {
                this.Enabled = false;
                return;
            }
            else
                this.Enabled = true;

            this.tmpClient = new Billing.DataObjects.ClientsView();
            this.client = new Billing.DataObjects.ClientsView();

            if (client == null)
            {
                this.tmpClient.ClientTypeID = 2;
                btBalance.Visible = false;
                this.openMode = Billing.WindowsBase.eOpenMode.New;
            }
            else
            {
                this.client = client;
                Copy(client, tmpClient);
                btBalance.Visible = true;
                valClientType.Enabled = false;
                this.openMode = Billing.WindowsBase.eOpenMode.Edit;
            }
            this.tmpClient.PropertyChanged += new PropertyChangedEventHandler(tmpClient_PropertyChanged);
            this.itemList = itemList;
            clientBindingSource.DataSource = this.tmpClient;
            lbBalance.Text = string.Empty;
        }

        void tmpClient_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (tmpClient.ClientTypeID == 2)
                switch (e.PropertyName)
                {
                    case "Name":
                        if (string.IsNullOrEmpty(tmpClient.Name))
                        {
                            tmpClient.ClientStatusID = 3;
                            ShowWarning(msgClientNameCleared);
                            valName.Select();
                        }
                        break;
                    case "Address":
                        if (string.IsNullOrEmpty(tmpClient.Address))
                        {
                            tmpClient.ClientStatusID = 3;
                            ShowWarning(msgClientAddressCleared);
                            valAddress.Select();
                        }
                        break;
                    case "IdentificationNumber":
                        if (string.IsNullOrEmpty(tmpClient.IdentificationNumber))
                        {
                            tmpClient.ClientStatusID = 3;
                            ShowWarning(msgClientIdentificationNumberCleared);
                            valIdentificationNumber.Select();
                        }
                        break;
                    case "ClientStatusID":
                        if (tmpClient.ClientStatusID != 3)
                            if (string.IsNullOrEmpty(tmpClient.Name))
                            {
                                ShowWarning(msgClientNameCleared);
                                tmpClient.ClientStatusID = 3;
                                valName.Select();
                                valClientStatus.SelectedIndex = 2;
                            }
                            else
                                if (string.IsNullOrEmpty(tmpClient.IdentificationNumber))
                                {
                                    ShowWarning(msgClientIdentificationNumberCleared);
                                    tmpClient.ClientStatusID = 3;
                                    valIdentificationNumber.Select();
                                    valClientStatus.SelectedIndex = 2;
                                }
                                else if (string.IsNullOrEmpty(tmpClient.Address))
                                {
                                    ShowWarning(msgClientAddressCleared);
                                    tmpClient.ClientStatusID = 3;
                                    valAddress.Select();
                                    valClientStatus.SelectedIndex = 2;
                                }
                        break;
                    case "TaxID":
                        if (!client.TaxID.Equals(tmpClient.TaxID))
                        {
                            if (ShowQuestion(msgTaxChangeQuestion) != DialogResult.Yes)
                            {
                                tmpClient.TaxID = client.TaxID;
                                if (client.TaxID == 1)
                                    valTax.SelectedIndex = 0;
                                if (client.TaxID == 2)
                                    valTax.SelectedIndex = 1;
                            }
                            else
                            {
                                ShowWarning(msgTaxChange);
                            }
                        }
                        break;
                    default:
                        break;
                }
        }

        private void LoadDictionaryData()
        {
            if (DesignMode) return;
            clientStatuseBindingSource.DataSource = context.ClientStatuses;
            clientTypeBindingSource.DataSource = context.ClientTypes;
            taxBindingSource.DataSource = context.Taxes;

            valClientStatus.DataSource = clientStatuseBindingSource;
            valClientType.DataSource = clientTypeBindingSource;
            valClientType.SelectedIndex = 1;
            valTax.DataSource = taxBindingSource;
        }

        private void Copy(Billing.DataObjects.ClientsView source, Billing.DataObjects.ClientsView destination)
        {
            if (source == null)
                return;

            Type t = source.GetType();
            System.Reflection.PropertyInfo[] props = t.GetProperties();

            foreach (System.Reflection.PropertyInfo pInf in props)
            {
                if (pInf.CanWrite && pInf.CanRead)
                {
                    pInf.SetValue(destination, pInf.GetValue(source, null), null);
                }
            }
        }

        private void Copy(Billing.DataObjects.ClientStatuse source, Billing.DataObjects.ClientStatuse destination)
        {
            destination.ID = source.ID;
            destination.Name = source.Name;
            destination.ModifiedDate = source.ModifiedDate;
            destination.CreatedDate = source.CreatedDate;
        }

        private void Copy(Billing.DataObjects.ClientType source, Billing.DataObjects.ClientType destination)
        {
            destination.ID = source.ID;
            destination.Name = source.Name;
            destination.ModifiedDate = source.ModifiedDate;
            destination.CreatedDate = source.CreatedDate;
        }

        private void DoCancel()
        {
            clientBindingSource.CancelEdit();

            if (Canceled != null)
                Canceled(this, EventArgs.Empty);

        }

        private void DoSave(bool close)
        {
            if (DesignMode) return;

            clientBindingSource.EndEdit();

            Copy(tmpClient, client);

            Control ctrl = this.ActiveControl;
            if (ctrl == null) ctrl = this;
            this.Focus();

            if (itemList != null)
                if (!itemList.Contains(client))
                {
                    if (string.IsNullOrEmpty(client.Name))
                    {
                        base.ShowWarning(msgNameMissing);
                        return;
                    }

                    int? ID = null;
                    if (!chbContractInfo.Checked)
                    {
                        client.ContractNumber = null;
                        client.ContractDate = null;
                    }

                    if (!ValidateData(client)) return;

                    context.ClientsAdd(ref ID, client.Key, client.IdentificationNumber, client.FirstName,
                        client.LastName, client.Name, client.Address, client.Email, client.ContactInfo,
                        client.Comment, client.ClientStatusID, client.ClientTypeID, client.TaxID, client.ContractAmount, client.ContractDate, client.ContractNumber, client.Budgeted);
                    client.ID = ID.Value;
                    itemList.Add(client);
                }
                else
                {
                    if (client == null)
                    {
                        base.ShowWarning(msgClientMissing);
                        ctrl.Focus();
                        return;
                    }

                    if (!chbContractInfo.Checked)
                    {
                        client.ContractNumber = null;
                        client.ContractDate = null;
                    }

                    if (!ValidateData(client)) return;


                    context.ClientsUpdate(client.ID, client.Key, client.IdentificationNumber, client.FirstName,
                        client.LastName, client.Name, client.Address, client.Email, client.ContactInfo,
                        client.Comment, client.ClientStatusID, client.ClientTypeID, client.TaxID, client.ContractAmount, client.ContractDate, client.ContractNumber, client.Budgeted);
                }


            if (Saved != null)
                Saved(this, EventArgs.Empty);

            if (close)
            {
                if (CloseRequest != null)
                    CloseRequest(this, EventArgs.Empty);
            }
            else
            {
                if (this.openMode == Billing.WindowsBase.eOpenMode.New)
                {
                    tmpClient = new Billing.DataObjects.ClientsView();
                    client = new Billing.DataObjects.ClientsView();
                    clientBindingSource.DataSource = tmpClient;
                }
            }
            ctrl.Focus();
        }

        private bool ValidateData(Billing.DataObjects.ClientsView client)
        {
            bool result = true;
            if (client.ClientStatusID == 0)
            {
                ShowWarning(msgClientStatusMissing);
                result = false;
            }

            if (client.ClientTypeID == 0)
            {
                ShowWarning(msgClientTypeMissing);
                result = false;
            }

            if (client.TaxID == 0)
            {
                ShowWarning(msgTaxMissing);
                result = false;
            }

            return result;
        }

        private void TBM_ToolClick(object sender, Infragistics.Win.UltraWinToolbars.ToolClickEventArgs e)
        {
            try
            {
                switch (e.Tool.Key)
                {
                    case "SaveAndClose":    // ButtonTool
                        DoSave(true);
                        break;

                    case "Save":    // ButtonTool
                        DoSave(false);
                        break;

                    case "Cancel":    // ButtonTool
                        DoCancel();
                        break;

                }
            }
            catch (Exception x)
            {
                base.ShowError(x);
            }
        }

        private void chbContractInfo_CheckedChanged(object sender, EventArgs e)
        {
            valContractNumber.Enabled = chbContractInfo.Checked;
            valContractDate.Enabled = valContractNumber.Enabled;
        }

        private void clientBindingSource_CurrentChanged(object sender, EventArgs e)
        {
            chbContractInfo.Checked = !(string.IsNullOrEmpty(client.ContractNumber));
        }

        private void btBalance_Click(object sender, EventArgs e)
        {
            if (DesignMode) return;

            lbBalance.Text = context.GetClientBalance(tmpClient.ID, null).Value.ToString("### ##0.00 " + System.Threading.Thread.CurrentThread.CurrentCulture.NumberFormat.CurrencySymbol);
        }

        private void valTax_EditorButtonClick(object sender, Infragistics.Win.UltraWinEditors.EditorButtonEventArgs e)
        {
            switch (e.Button.Key)
            {
                case "Calculate":
                    if (openMode == Billing.WindowsBase.eOpenMode.New) return;

                    AnalysisSubject analysisSubject = new AnalysisSubject();
                    analysisSubject.AnalysisType = AnalysisType.ClientUpdate;

                    analysisSubject.SourceClient = client;
                    analysisSubject.DestinationClient = tmpClient;

                    analysisSubject.SourceAccount = null;
                    analysisSubject.StartDate = DateTime.Today.AddDays(-DateTime.Today.Day + 1);
                    analysisSubject.EndDate = DateTime.Today;

                    using (CalculatorForm f = new CalculatorForm())
                    {
                        f.Analyse(analysisSubject);
                    }
                    break;
                default:
                    break;
            }
        }
    }
}
